package xlog

import (
	"bytes"
	"fmt"
	"os"
	"sync"
)

// XLogger
// 默认按天进行分割
type XLogger struct {
	mu      sync.Mutex
	bufPool sync.Pool
	config  *Config
}

// New 初始化
func New() *XLogger {
	obj := &XLogger{
		config: NewDefaultConfig(),
	}
	obj.bufPool.New = func() interface{} { return new(bytes.Buffer) }
	return obj
}

func (x *XLogger) getBuf() *bytes.Buffer {
	return x.bufPool.Get().(*bytes.Buffer)
}

func (x *XLogger) putBuf(buf *bytes.Buffer) {
	buf.Reset()
	x.bufPool.Put(buf)
}

// Println
func (x *XLogger) Println(v ...interface{}) {
	x.print(os.Stdout, "", v...)
}

// Printf
func (x *XLogger) Printf(format string, v ...interface{}) {
	x.print(os.Stdout, "", fmt.Sprintf(format, v...))
}

// Debug
func (x *XLogger) Debug(v ...interface{}) {
	if x.checkLevel(LevelDebug) { // 判断是否满足处理条件
		x.print(os.Stdout, x.getLevelPrefixWithBrackets(LevelDebug), v...)
	}
}

func (x *XLogger) Debugf(format string, v ...interface{}) {
	if x.checkLevel(LevelDebug) { // 判断是否满足处理条件
		x.print(os.Stdout, x.getLevelPrefixWithBrackets(LevelDebug), fmt.Sprintf(format, v...))
	}
}

// Info
func (x *XLogger) Info(v ...interface{}) {
	if x.checkLevel(LevelInfo) { // 判断是否满足处理条件
		x.print(os.Stdout, x.getLevelPrefixWithBrackets(LevelInfo), v...)
	}
}

// Infof
func (x *XLogger) Infof(format string, v ...interface{}) {
	if x.checkLevel(LevelInfo) { // 判断是否满足处理条件
		x.print(os.Stdout, x.getLevelPrefixWithBrackets(LevelInfo), fmt.Sprintf(format, v...))
	}
}

// Error
func (x *XLogger) Error(v ...interface{}) {
	if x.checkLevel(LevelError) { // 判断是否满足处理条件
		x.printErr(os.Stderr, x.getLevelPrefixWithBrackets(LevelError), v...)
	}
}

// Errorf
func (x *XLogger) Errorf(format string, v ...interface{}) {
	if x.checkLevel(LevelError) { // 判断是否满足处理条件
		x.printErr(os.Stderr, x.getLevelPrefixWithBrackets(LevelError), fmt.Sprintf(format, v...))
	}
}

// Warning
func (x *XLogger) Warning(v ...interface{}) {
	if x.checkLevel(LevelWarn) { // 判断是否满足处理条件
		x.print(os.Stdout, x.getLevelPrefixWithBrackets(LevelWarn), v...)
	}
}

// Warningf
func (x *XLogger) Warningf(format string, v ...interface{}) {
	if x.checkLevel(LevelWarn) { // 判断是否满足处理条件
		x.print(os.Stdout, x.getLevelPrefixWithBrackets(LevelWarn), fmt.Sprintf(format, v...))
	}
}

// Fatal
func (x *XLogger) Fatal(v ...interface{}) {
	x.printErr(os.Stderr, x.getLevelPrefixWithBrackets(LevelFatal), v...)
	os.Exit(1)
}

// Fatalf
func (x *XLogger) Fatalf(format string, v ...interface{}) {
	x.printErr(os.Stderr, x.getLevelPrefixWithBrackets(LevelFatal), fmt.Sprintf(format, v...))
	os.Exit(1)
}

// Panic
func (x *XLogger) Panic(v ...interface{}) {
	x.printErr(os.Stderr, x.getLevelPrefixWithBrackets(LevelPanic), v...)
	panic(fmt.Sprint(v...))
}

// Panicf
func (x *XLogger) Panicf(format string, v ...interface{}) {
	fmtStr := fmt.Sprintf(format, v...)
	x.printErr(os.Stderr, x.getLevelPrefixWithBrackets(LevelPanic), fmtStr)
	panic(fmtStr)
}
